/*
 * @desc js选择器
 * */
define(['objecter'], function(objecter){
    var query = function(){
        this.init.apply(this, arguments);
    },

    _methods = {
        /**
         * @desc 查找元素
         * @param <Dom/String> selector 选择器
         * @param <Dom/String> parentNode 父元素
         * @return <Array>
         * */
        find : function(selector, parentNode){
            var results = [];
            if(selector && typeof selector == 'string' ){
                selector = selector.split(',');
                for(var i = 0; i < selector.length; i++){
                    results = results.concat(_query(selector[i], parentNode));
                }
            }else if(objecter.isDOM(selector)){
                results.push(selector);
            }else if(objecter.isArray(selector)){
                for(var i = 0; i < selector.length; i++){
                    results = results.concat(this.find(selector[i], parentNode));
                }
            }
            results = _unique(results);

            return results;
        },

        //查找父元素
        parent : function(selector, parentSelector, loop, bFisrt){
            var nodes = this.find(selector),
                parentNodes = [],
                parents = (objecter.isDOM(parentSelector) || typeof parentSelector == 'string' || objecter.isArray(parentSelector)) ? this.find(parentSelector) : null,
                results = [];

            _parent(nodes);
            if(loop === true){
                while(parentNodes.length > 0){
                    _parent(parentNodes);
                }
            }

            function _parent(_nodes) {
                parentNodes = [];
                if(bFisrt === true && results.length > 0) return;
                for (var i = 0, b = false, node; i < _nodes.length; i++) {
                    b = false;
                    nodeParent = _nodes[i].parentNode;
                    if(nodeParent != null) parentNodes.push(nodeParent);
                    if (parents != null) {
                        for (var j = 0; j < parents.length; j++) {
                            if (parents[j] == nodeParent && nodeParent != null) {
                                b = true;
                                break;
                            }
                        }
                    } else {
                        if (nodeParent != null) b = true;
                    }

                    if (b) results.push(nodeParent);

                    if(bFisrt === true && b) break;
                }
            }
            results = _unique(results);

            return results;
        },

        //查找多个层级元素
        parents : function(selector, parentSelector){
            var results = this.parent(selector, parentSelector, true);

            return results;
        },

        //查找符合条件父元素则停止
        closest : function(selector, parSelector){
            var nodes = this.find(selector), results = [];
            for(var i = 0; i < nodes.length; i++){
                results = results.concat(this.parent(nodes[i], parSelector, true, true));
            }
            results = _unique(results);

            return results;
        },

        //查找子元素
        children : function(selector, childSelector){
            var nodes = this.contents(selector), results = [];
            for(var i = 0; i < nodes.length; i++){
                if(objecter.isElementNode(nodes[i])) results.push(nodes[i]);
            }

            return results;
        },

        //查找子元素包括文本节点
        contents : function(selector, childSelector){
            var nodes = this.find(selector), results = [];
            for(var i = 0; i < nodes.length; i++){
                var childNodes = nodes[i].childNodes || [];
                for(var j = 0; j < childNodes.length; j++){
                    results.push(childNodes[j]);
                }
            }
            results = _unique(results);

            return results;
        },

        //查找除自已外的同辈元素
        siblings : function(selector, sibSelector){

        },

        //查找之前元素
        prev : function(selector, prevSelector){

        },

        //查找之前所有同辈元素
        prevAll : function(selector, prevSelector){

        },

        //查找后面元素
        next : function(selector, nextSelector){

        },

        //查找后面所有同辈元素
        nextAll : function(selector, nextSelector){

        }
    };

    for(var i in _methods){
        query[i] = _methods[i];
    }

    query.fn = query.prototype = {
        init : function(selector){
            var nodes = _methods.find(selector);
            return nodes;
        }
    };

    /**
     * @desc 搜索指定类名的元素
     * @param <String> searchClass 搜索的类名
     * @param <Dom> node 指定需要搜索的节点
     * @param <String> tag 指定需要搜索的元素标签
     * @return <Array>
     * */
    function getElementsByClassName(searchClass, node, tag){
        var i, result = [];
        tag = tag || '';
        if(document.getElementsByClassName){
            var nodes = (node || document).getElementsByClassName(searchClass);
            for(i = 0 ; typeof(node = nodes[i++]) !== 'undefined'; i++){
                if(tag !== '*' && node.tagName === tag.toUpperCase()){
                    result.push(node);
                }else{
                    result.push(node);
                }
            }
            return result;
        }else{
            node = node || document;
            tag = tag || '*';
            var classes = searchClass.split(' '),
                elements = (tag === '*' && node.all) ? node.all : node.getElementsByTagName(tag),
                patterns = [],
                current,
                match;
            i = classes.length;
            while(--i >= 0){
                patterns.push(new RegExp('(^|\\s+)' + classes[i] + '(\\s+|$)'));
            }
            var j = elements.length;
            while(--j >= 0){
                current = elements[j];
                match = false;
                for(var k=0, kl=patterns.length; k<kl; k++){
                    match = patterns[k].test(current.className);
                    if (!match){
                        break;
                    }
                }
                if (match){
                    result.push(current);
                }
            }
            return result;
        }
    }

    /**
     * @desc 搜索指定类名的元素
     * @param <String> search 搜索的属性
     * @param <Dom> node 指定需要搜索的节点
     * @param <String> tag 指定需要搜索的元素标签
     * @return <Array>
     * */
    function getElementsByAttribute(search, node, tag){
        var reg = /([\*a-zA-Z1-6]*)?(\[(\w+)\s*(\^|\$|\*|\||~|!)?=?\s*([\w\u00C0-\uFFFF\s\-_\.]+)?\])?/,
            node = node || document,
            agent = search.match(reg),
            tag = tag || "*",
            attribute = agent[3],
            type =  agent[4]+"=",
            value = agent[5],
            nodes = [],
            elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag),
            length = elements.length;
        if((!!document.querySelectorAll) && type != "!="){
            elements = document.querySelectorAll(search);
            for(var i=0,length = elements.length;i < length;i++){
                nodes.push(elements[i]);
            }
            return nodes
        }
        while(--length >= 0){
            var current = elements[length],
                _value = current.getAttribute(attribute);
            if(typeof _value === "string" && _value.length > 0){
                if(!!value){
                    var condition =
                            type === "=" ?//完全等于
                        _value === value :
                            type === "!=" ?//不等于
                        _value != value :
                            type === "*=" ?//包含
                        _value.indexOf(value) >= 0 :
                            type === "~=" ?//匹配当中的某个单词，如<span class="red bold">警告</span>
                        (" " + _value + " ").indexOf(value) >= 0:
                            type === "^=" ?//以XX开头
                        _value.indexOf(value) === 0 :
                            type === "$=" ?//以XX结尾
                        _value.slice(-_value.length) === value:
                            type === "|=" ?//匹配属性值为XX或以XX-打头的元素
                        _value === value ||  _value.substring(0,value.length+1) === value+"-" :
                        false;
                    condition && nodes.push(current);
                }else{
                    nodes.push(current)
                }
            }
        }
        return nodes;
    }

    /**
     * @desc 寻找子元素
     * @param <String> selector 选择器
     * @param <Dom> parentNode 指定父节点
     * @return <Array>
     * */
    function find(selector, parentNode){
        //如果不传入父节点的话，默认为body
        if(parentNode == undefined) parentNode = document;
        selector = selector || '*';
        var results = [], arr = [];

            //加号选择器
        if(/\w+\+\w/.test(selector)){
            var values = selector.split('+'),
                first = values[0], node;
            values.shift();
            selector = values.join('+');
            node = find(first, parentNode);
            for(var i = 0; i < node.length; i++){
                arr = arr.concat(find(selector, node[i]));
            }
        }

        //子选择器
        else if(/\w+\>\w/.test(selector)){
            var values = selector.split('>'),
                first = values[0],
                second = values[1];
            values.shift();
            values.shift();
            selector = values.join('>');
            node = find(first, parentNode);
            //查找所有子元素
            for(var i = 0, subNode = []; i < node.length; i++){
                for(var j = 0; j < node.length; j++){
                    subNode = subNode.concat(children(node[i], second));
                }
            }

            //子元素往下继续查找
            if(values.length > 0){
                for(var i = 0; i < subNode.length; i++){
                    arr = arr.concat(find(selector, subNode[i]));
                }
            }else{
                arr = subNode;
            }
        }

        //属性选择器
        else if(/\[[^\[]+\]/.test(selector)){
            arr = getElementsByAttribute(selector, parentNode);
        }

        else{
            arr = _find(selector, parentNode);
        }

        if(arr && arr.length > 0){
            for(var i = 0; i< arr.length; i++){
                if(arr[i]) results.push(arr[i]);
            }
        }

        return results;
    }

    //单个查询
    function _query(selector, parentNode){
        selector = formateSelector(selector);
        //按照空格分割参数
        var values = selector.split(/\s+/);

        //如果只有一个选择参数的话，就直接调用dom方法返回结果。
        if(values.length == 1){
            return find(values[0], parentNode);
        }

        //每次迭代都会产生许多符合参数的结果节点,这里结果节点的名称为parentNodes，第一次循环默认为document
        var parentNodes = [document];
        if(objecter.isDOM(parentNode)){
            parentNodes = [parentNode];
        }else if(typeof parentNode == 'string'){
            parentNodes = find(parentNode);
        }

        //外层循环为迭代每个传入的参数
        for(var i = 0; i < values.length; i++){
            var results = [];

            //内层循环为迭代每个结果节点
            for(var j = 0; j < parentNodes.length; j++){
                //find就是上边的那个函数，就是选择某个节点的子节点的
                var result = find(values[i], parentNodes[j]);
                results = results.concat(result);
            }

            results = _unique(results);
            parentNodes = results;
        }

        return parentNodes;

    }

    //单个查找
    function _find(selector, parentNode){
        var arr = [];
        //id选择
        if(/^\#/.test(selector)){
            arr = [document.getElementById(selector.substr(1))];
        }

        //类选择
        else if(/^\./.test(selector)){
            arr = getElementsByClassName(selector.substr(1), parentNode);
        }

        //元素名称选择
        else{
            arr = parentNode.getElementsByTagName(selector);
        }

        return arr;
    }

    //查找子元素
    function children(node, selector){
        var nodes = node.childNodes;
        for(var i = 0, arr = []; i < nodes.length; i++){
            arr.push(nodes[i]);
        }
        return filter(arr, selector);
    }

    //属性过滤
    function filter(nodes, selector){
        for(var i = 0, arr = [], b; i < nodes.length; i++){
            b = _filter(nodes[i], selector);
            if(b != false){
                arr.push(nodes[i]);
            }
        }

        return arr;
    }

    //单个元素属性过滤
    function _filter(node, selector){
        var b = false;

        //id选择
        if(/^\#/.test(selector)){
            if(node.id == selector.substr(1)) b = node;
        }

        //类选择
        else if(/^\./.test(selector)){
            var className = node.className || '';
            className = className.split(' ');
            for(var i = 0, selector = selector.substr(1); i < className.length; i++){
                if(selector == className[i]){
                    b = node;
                    break;
                }
            }
        }

        //元素名称选择
        else{
            if(node.tagName && node.tagName.toLowerCase() == selector.toLowerCase()) b = node;
        }

        return b;
    }

    //找出含有项
    function findHas(arr1, arr2){
        var results = [];
        for(var i = 0, b; i < arr1.length; i ++){
            b = false;
            for(var j = 0; j < arr2.length; j++){
                if(arr1[i] == arr2[j] && arr1[i] != null) b = true;
            }
            if(b) results.push(arr1[i]);
        }

        return results;
    }


    //元素去重
    function _unique(arr){
        var list = [];

        for(var i = 0, b; i < arr.length; i++){
            b = false;
            for(var j = 0; j < list.length; j++){
                if(list[j] == arr[i]) b= true;
            }
            if(!b) list.push(arr[i]);
        }

        return list;
    }

    return query;

    //格式化选择器
    function formateSelector(str){
        str = trim(str);
        str = str.replace(/\s*\>\s*/g, '>')
            .replace(/\s*\+\s*/g, '+')
            .replace(/\s*\~\s*/g, '~')
            .replace(/\s*\:\s*/g, ':')
            .replace(/\s*\(\s*/g, '(')
            .replace(/\s*\)\s*/g, ')')
            .replace(/\[\s+/g, '[')
            .replace(/\s+\]/g, ']')
            .replace(/\s*\=\s*/g, '=')
            .replace(/\s*\~\s*\=\s*/g, '~=')
            .replace(/\s*\|\s*\=\s*/g, '|=')
            .replace(/\s*\^\s*\=\s*/g, '^=')
            .replace(/\s*\$\s*\=\s*/g, '$=')
            .replace(/\s*\*\s*\=\s*/g, '*=')
        return str;
    }

    //删除空格
    function trim(str) {
        return str.replace(/^\s+|\s+$/g, '');
    }

});